/**
 * Title :	jFamilyTree generator
 * Description: jFamilyTree generator
 * Version:	provider
 * Copyright (c) 2001-2008
 * Terms of use:see license agreement at http://treebolic.sourceforge.net/en/license.htm
 * Author: Bernard Bou
 * Company: bsys
 */
package jFamilyTree.site;

import java.io.IOException;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.util.StringTokenizer;

import org.w3c.dom.Document;

import sun.net.ftp.FtpLoginException;
import jFamilyTree.Messages;

/**
 * FTP extended client
 * 
 * @author Bernard Bou
 */
class FtpClientX extends sun.net.ftp.FtpClient
{
	/**
	 * MKDIR a directory on a remote FTP server
	 * 
	 * @param remoteDirectory
	 *        remote directory to create
	 * @throws IOException
	 */
	public void mkdir(String remoteDirectory) throws IOException
	{
		try
		{
			issueCommandCheck("MKD " + remoteDirectory); //$NON-NLS-1$
		}
		catch (IOException e1)
		{
			// Well, "/" might not be the file delimitor for this particular ftp server,
			// so let's try a series of "cd" and "mkd" commands to get to the right place.

			String pathElement = null;

			// cd path
			StringTokenizer t = new StringTokenizer(remoteDirectory, "/"); //$NON-NLS-1$
			while (t.hasMoreElements())
			{
				pathElement = t.nextToken();

				// cd this pathElement
				try
				{
					cd(pathElement);
				}
				catch (IOException e2)
				{
					try
					{
						issueCommandCheck("MKDIR " + pathElement); //$NON-NLS-1$
						cd(pathElement);
					}
					catch (IOException e3)
					{
						// giving up.
						throw e1;
					}
				}
			}
		}
	}

	/**
	 * MKDIR a directory on a remote FTP server
	 * 
	 * @throws IOException
	 */
	public void passive() throws IOException
	{
		try
		{
			issueCommandCheck("PASV "); //$NON-NLS-1$
		}
		catch (IOException e1)
		{
		}
	}
}

/**
 * FTP site maker
 * 
 * @author Bernard Bou
 */
public class FtpSiteMaker extends SiteMaker
{
	/**
	 * Server
	 */
	private String theServer;

	/**
	 * Server directory
	 */
	private String theDirectory;

	/**
	 * Server login
	 */
	private String theLogin;

	/**
	 * Server login password
	 */
	private String thePassword;

	/**
	 * FTP client
	 */
	private FtpClientX theClient;

	// C O N S T R U C T O R

	/**
	 * Constructor
	 * 
	 * @param thisDocument
	 *        DOM document (source)
	 * @param thisRepository
	 *        repository (source)
	 * @param thisImageRepository
	 *        image repository (source)
	 * @param thisHtmlFile
	 *        HTML file (target)
	 * @param thisXmlFile
	 *        XML file (target)
	 * @param thisTitle
	 *        HTML page title (target)
	 * @param thisServer
	 *        server (target)
	 * @param thisDirectory
	 *        server directory (target)
	 * @param thisLogin
	 *        server login (target)
	 * @param thisPassword
	 *        server login password (target)
	 * @throws URISyntaxException
	 * @throws IOException
	 */
	public FtpSiteMaker(Document thisDocument, String thisRepository, String thisImageRepository, String thisHtmlFile, String thisXmlFile, String thisTitle, String thisServer, String thisDirectory, String thisLogin, String thisPassword)
			throws URISyntaxException, IOException
	{
		super(thisDocument, thisRepository, thisImageRepository, thisHtmlFile, thisXmlFile, thisTitle);

		theServer = thisServer;
		theDirectory = thisDirectory;
		theLogin = thisLogin;
		thePassword = thisPassword;
		theClient = new FtpClientX();
	}

	// I N T E R F A C E

	/*
	 * (non-Javadoc)
	 * @see jFamilyTree.site.SiteMaker#makeOutStream(java.lang.String)
	 */
	public OutputStream makeOutStream(String thisString) throws MalformedURLException, IOException
	{
		return theClient.put(thisString);
	}

	/*
	 * (non-Javadoc)
	 * @see jFamilyTree.generator.sitemaker.SiteMaker#connect()
	 */
	public boolean connect()
	{
		try
		{
			notifyOperation(Messages.getString("FtpSiteMaker.4"), PROGRESSCONNECT); //$NON-NLS-1$
			theClient.openServer(theServer);

			try
			{
				notifyOperation(Messages.getString("FtpSiteMaker.1"), PROGRESSCONNECT + 2); //$NON-NLS-1$
				theClient.login(theLogin, thePassword);
			}
			catch (FtpLoginException thisException)
			{
				theClient.closeServer();
				throw new IOException("LOGGING IN"); //$NON-NLS-1$
			}

			notifyOperation(Messages.getString("FtpSiteMaker.2"), PROGRESSCONNECT + 2); //$NON-NLS-1$
			theClient.passive();

			notifyOperation(Messages.getString("FtpSiteMaker.3"), PROGRESSCONNECT + 3); //$NON-NLS-1$
			theClient.binary();

			try
			{
				notifyOperation("CD " + theDirectory, PROGRESSCONNECT + 4); //$NON-NLS-1$
				theClient.cd(theDirectory);
			}
			catch (IOException thisException)
			{
				theClient.mkdir(theDirectory);
				theClient.cd(theDirectory);
			}
		}
		catch (IOException thisException)
		{
			notifyOperation(Messages.getString("FtpSiteMaker.10") + thisException.getMessage(), PROGRESSCONNECTCOMPLETE); //$NON-NLS-1$
			return false;
		}

		notifyOperation(Messages.getString("FtpSiteMaker.5"), PROGRESSCONNECTCOMPLETE); //$NON-NLS-1$
		return true;
	}

	/*
	 * (non-Javadoc)
	 * @see jFamilyTree.generator.sitemaker.SiteMaker#disconnect()
	 */
	public boolean disconnect()
	{
		try
		{
			theClient.closeServer();
		}
		catch (IOException thisException)
		{
			System.err.println(thisException.toString());
			thisException.printStackTrace();
			return false;
		}
		return true;
	}

	/*
	 * (non-Javadoc)
	 * @see jFamilyTree.generator.sitemaker.SiteMaker#changeFolder(java.lang.String)
	 */
	public boolean changeFolder(String thisRelativeDirectory)
	{
		try
		{
			theClient.cd(thisRelativeDirectory);
		}
		catch (IOException thisException)
		{
			try
			{
				notifyOperation("MKDIR " + thisRelativeDirectory, PROGRESSXFERIMAGES + 2); //$NON-NLS-1$
				theClient.mkdir(thisRelativeDirectory);
				notifyOperation("CD " + thisRelativeDirectory, PROGRESSXFERIMAGES + 2); //$NON-NLS-1$
				theClient.cd(thisRelativeDirectory);
			}
			catch (IOException thisSubException)
			{
				return false;
			}
		}
		return true;
	}
}
